package com.dy.yunying.biz.service.hongbao.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dy.yunying.api.constant.Constant;
import com.dy.yunying.api.entity.GameRole;
import com.dy.yunying.api.entity.ParentGameArea;
import com.dy.yunying.api.entity.ParentGameDO;
import com.dy.yunying.api.entity.WanGameDO;
import com.dy.yunying.api.entity.hongbao.*;
import com.dy.yunying.api.entity.raffle.RaffleActivity;
import com.dy.yunying.api.enums.*;
import com.dy.yunying.api.req.hongbao.*;
import com.dy.yunying.api.resp.hongbao.NodeData;
import com.dy.yunying.api.resp.hongbao.NodeParentData;
import com.dy.yunying.api.vo.hongbao.ActivityVo;
import com.dy.yunying.biz.dao.ads.hongbao.*;
import com.dy.yunying.biz.dao.manage.GameRoleMapper;
import com.dy.yunying.biz.dao.manage.ParentGameAreaMapper;
import com.dy.yunying.biz.dao.manage.ext.GameDOMapperExt;
import com.dy.yunying.biz.dao.manage.ext.ParentGameDOMapperExt;
import com.dy.yunying.biz.dao.manage.ext.PromotionChannelDOMapperExt;
import com.dy.yunying.biz.dao.manage.ext.WanGameChannelInfoDOMapperExt;
import com.dy.yunying.biz.service.hongbao.ActivityService;
import com.dy.yunying.biz.service.hongbao.HbActivityRoleInfoService;
import com.dy.yunying.biz.service.manage.AdRoleGameService;
import com.dy.yunying.biz.service.manage.GameService;
import com.dy.yunying.biz.service.raffle.RaffleActivityService;
import com.dy.yunying.biz.utils.DateUtils;
import com.pig4cloud.pig.admin.api.dto.UserInfo;
import com.pig4cloud.pig.admin.api.feign.RemoteUserService;
import com.pig4cloud.pig.common.core.constant.CommonConstants;
import com.pig4cloud.pig.common.core.constant.SecurityConstants;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author yuwenfeng
 * @description: 红包活动服务
 * @date 2021/10/23 10:47
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ActivityServiceImpl extends ServiceImpl<HbActivityMapper, HbActivity> implements ActivityService {
	private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd HH:mm:ss.SSS").toFormatter();

	private final HbActivityMapper activityMapper;

	private final HbActivityAreaMapper activityAreaMapper;

	private final HbActivityChannelMapper activityChannelMapper;

	private final HbCashLimitMapper cashLimitMapper;

	private final HbActivityGameMapper activityGameMapper;

	private final ParentGameDOMapperExt parentGameDOMapperExt;

	private final GameDOMapperExt gameDOMapperExt;

	private final PromotionChannelDOMapperExt promotionChannelDOMapperExt;

	private final WanGameChannelInfoDOMapperExt wanGameChannelInfoDOMapperExt;

	private final ParentGameAreaMapper parentGameAreaMapper;

	private final HbInvestRecordMapper investRecordMapper;

	private final HbRedpackConfigMapper redpackConfigMapper;

	private final HbReceivingRecordMapper receivingRecordMapper;

	private final HbActivityRoleInfoMapper activityRoleInfoMapper;

	private final HbRedpackRoleInfoMapper redpackRoleInfoMapper;

	private final GameRoleMapper gameRoleMapper;

	private final AdRoleGameService adRoleGameService;

	private final GameService gameService;

	private final HbCashConfigMapper cashConfigMapper;

	private final HbActivityNoticeMapper activityNoticeMapper;

	private final HbInvitationTopMapper invitationTopMapper;

	private final PopupNoticeMapper popupNoticeMapper;

	private final PopupNoticeAreaMapper popupNoticeAreaMapper;

	private final PopupNoticeChannelMapper popupNoticeChannelMapper;

	private final PopupNoticeGameMapper popupNoticeGameMapper;

	private final RemoteUserService remoteUserService;

	private final HbActivityDynamicTypeMapper hbActivityDynamicTypeMapper;

	private final HbActivityRoleInfoService hbActivityRoleInfoService;

	private final RaffleActivityService raffleActivityService;

	@Autowired
	private StringRedisTemplate stringRedisTemplate;

	@Override
	public Page<ActivityVo> selectActivityPage(Page<HbActivity> page, QueryWrapper<SelectActivityPageReq> query) {
		Page<ActivityVo> result = activityMapper.selectActivityVoPage(page, query);
		if (CollectionUtils.isNotEmpty(result.getRecords())) {
			List<WanGameDO> gameList = gameDOMapperExt.selectList(new QueryWrapper<WanGameDO>().eq("isdelete", Constant.DEL_NO));
			List<NodeParentData> allParentChannelList = promotionChannelDOMapperExt.selectAllChannel();
			List<NodeParentData> allSubChannelList = wanGameChannelInfoDOMapperExt.selectAllSubNodeList();
			List<ParentGameArea> areaList = parentGameAreaMapper.selectList(new QueryWrapper<ParentGameArea>());
			List<Long> activityIdResult = result.getRecords().stream().map(ActivityVo::getId).collect(Collectors.toList());
			//结果集的渠道范围
			List<HbActivityChannel> allActivityChannelList = activityChannelMapper.selectList(new QueryWrapper<HbActivityChannel>().in("activity_id", activityIdResult));
			//结果集的区服范围
			List<HbActivityArea> allActivityAreaList = activityAreaMapper.selectList(new QueryWrapper<HbActivityArea>().in("activity_id", activityIdResult).eq("source_type", SourceTypeEnum.HB.getType()));
			//结果集的游戏范围
			List<HbActivityGame> allActivityGameList = activityGameMapper.selectList(new QueryWrapper<HbActivityGame>().in("activity_id", activityIdResult));
			List<NodeParentData> childChannelList;
			List<NodeParentData> subChannelList;
			List<WanGameDO> childGameList;
			List<ParentGameArea> childAreaList;
			Date nowTime = new Date();
			for (ActivityVo vo : result.getRecords()) {
				//渠道范围
				List<HbActivityChannel> activityChannelList = allActivityChannelList.stream().filter(ac -> ac.getActivityId().equals(vo.getId())).collect(Collectors.toList());
				if (CollectionUtils.isNotEmpty(activityChannelList)) {
					List<String[]> channelList = new ArrayList<String[]>();
					List<String[]> channelDataList = new ArrayList<String[]>();
					String[] channelArr;
					for (HbActivityChannel activityChannel : activityChannelList) {
						if (1 == activityChannel.getChannelRange()) {
							childChannelList = allParentChannelList.stream().filter(t -> StringUtils.isNotBlank(t.getPId()) && t.getPId().equalsIgnoreCase(activityChannel.getChannelCode())).collect(Collectors.toList());
							if (CollectionUtils.isNotEmpty(childChannelList)) {
								for (NodeParentData childChannel : childChannelList) {
									subChannelList = allSubChannelList.stream().filter(t -> StringUtils.isNotBlank(t.getPId()) && t.getPId().equalsIgnoreCase(childChannel.getNodeId())).collect(Collectors.toList());
									if (CollectionUtils.isNotEmpty(subChannelList)) {
										for (NodeParentData subChannel : subChannelList) {
											channelArr = new String[]{activityChannel.getChannelCode(), childChannel.getNodeId(), subChannel.getNodeId()};
											channelList.add(channelArr);
										}
									} else {
										channelArr = new String[]{activityChannel.getChannelCode(), childChannel.getNodeId()};
										channelList.add(channelArr);
									}
								}
							} else {
								channelArr = new String[]{activityChannel.getChannelCode()};
								channelList.add(channelArr);
							}
							String[] channelDataArr = new String[]{activityChannel.getChannelCode()};
							channelDataList.add(channelDataArr);
						} else if (2 == activityChannel.getChannelRange()) {
							subChannelList = allSubChannelList.stream().filter(t -> StringUtils.isNotBlank(t.getPId()) && t.getPId().equals(activityChannel.getChildChannelCode())).collect(Collectors.toList());
							if (CollectionUtils.isNotEmpty(subChannelList)) {
								for (NodeParentData childChannel : subChannelList) {
									channelArr = new String[]{activityChannel.getChannelCode(), activityChannel.getChildChannelCode(), childChannel.getNodeId()};
									channelList.add(channelArr);
								}
							} else {
								channelArr = new String[]{activityChannel.getChannelCode(), activityChannel.getChildChannelCode()};
								channelList.add(channelArr);
							}
							String[] channelDataArr = new String[]{activityChannel.getChannelCode(), activityChannel.getChildChannelCode()};
							channelDataList.add(channelDataArr);
						} else if (3 == activityChannel.getChannelRange()) {
							channelArr = new String[]{activityChannel.getChannelCode(), activityChannel.getChildChannelCode(), activityChannel.getSubChannelCode()};
							channelList.add(channelArr);
							String[] channelDataArr = new String[]{activityChannel.getChannelCode(), activityChannel.getChildChannelCode(), activityChannel.getSubChannelCode()};
							channelDataList.add(channelDataArr);
						}
					}
					vo.setChannelList(channelList);
					vo.setChannelDataList(channelDataList);
				}
				//游戏范围
				List<HbActivityGame> activityGameList = allActivityGameList.stream().filter(ac -> ac.getActivityId().equals(vo.getId())).collect(Collectors.toList());
				if (CollectionUtils.isNotEmpty(activityGameList)) {
					List<Long[]> gameArrList = new ArrayList<Long[]>();
					List<Long[]> gameDataList = new ArrayList<Long[]>();
					Long[] gameArr;
					Long[] gameDataArr;
					for (HbActivityGame activityGame : activityGameList) {
						if (1 == activityGame.getGameRange()) {
							childGameList = gameList.stream().filter(t -> null != t.getPgid() && t.getPgid().equals(activityGame.getGameId())).collect(Collectors.toList());
							if (CollectionUtils.isNotEmpty(childGameList)) {
								for (WanGameDO game : childGameList) {
									gameArr = new Long[]{activityGame.getGameId(), game.getId()};
									gameArrList.add(gameArr);
								}
							} else {
								gameArr = new Long[]{activityGame.getGameId()};
								gameArrList.add(gameArr);
							}
							gameDataArr = new Long[]{activityGame.getGameId()};
							gameDataList.add(gameDataArr);
						} else if (2 == activityGame.getGameRange()) {
							gameArr = new Long[]{activityGame.getGameId(), activityGame.getChildGameId()};
							gameArrList.add(gameArr);
							gameDataArr = new Long[]{activityGame.getGameId(), activityGame.getChildGameId()};
							gameDataList.add(gameDataArr);
						}
					}
					vo.setGameList(gameArrList);
					vo.setGameDataList(gameDataList);
				}
				//游戏区服
				List<HbActivityArea> activityAreaList = allActivityAreaList.stream().filter(ac -> ac.getActivityId().equals(vo.getId())).collect(Collectors.toList());
				if (CollectionUtils.isNotEmpty(activityAreaList)) {
					List<Long[]> areaArrList = new ArrayList<Long[]>();
					List<Long[]> areaDataList = new ArrayList<Long[]>();
					Long[] areaArr;
					Long[] areaDataArr;
					for (HbActivityArea activityArea : activityAreaList) {
						if (1 == activityArea.getAreaRange()) {
							childAreaList = areaList.stream().filter(t -> null != t.getParentGameId() && t.getParentGameId().equals(activityArea.getGameId())).collect(Collectors.toList());
							if (CollectionUtils.isNotEmpty(childAreaList)) {
								for (ParentGameArea area : childAreaList) {
									areaArr = new Long[]{activityArea.getGameId(), area.getAreaId()};
									areaArrList.add(areaArr);
								}
							} else {
								areaArr = new Long[]{activityArea.getGameId()};
								areaArrList.add(areaArr);
							}
							areaDataArr = new Long[]{activityArea.getGameId()};
							areaDataList.add(areaDataArr);
						} else if (2 == activityArea.getAreaRange()) {
							areaArr = new Long[]{activityArea.getGameId(), activityArea.getAreaId()};
							areaArrList.add(areaArr);
							areaDataArr = new Long[]{activityArea.getGameId(), activityArea.getAreaId()};
							areaDataList.add(areaDataArr);
						}
					}
					vo.setAreaList(areaArrList);
					vo.setAreaDataList(areaDataList);
				}
				//这里给定制红包增加游戏任务的逻辑
				Integer activityType =  vo.getActivityType();
				//定制红包
				if (HbActivityTypeEnum.CUSTOM.getType() == activityType) {
					List<Long[]> voGameList = vo.getGameList();
					//获取到所有主游戏
					Set<Long> pgidSet = voGameList.stream().map(v -> v[0]).collect(Collectors.toSet());
					//如果只存在1个主游戏，设置状态为可
					if(pgidSet != null && pgidSet.size() == 1){
						vo.setTaskDisableFlag(1);
						//存储主游戏
						vo.setPgid(pgidSet.iterator().next());
					}
				}
			}
		}
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public R addActivity(ActivityReq activityReq) {
		//判断时间段内是否存在同类型活动
		Date startTime = DateUtils.stringToDate(activityReq.getStartTime(), DateUtils.YYYY_MM_DD_HH_MM_SS);
		if (null == startTime) {
			return R.failed("开始时间不合法");
		}
		if (startTime.getTime() < DateUtils.getStartTimeStamp()) {
			return R.failed("开始时间不能比当前日期0点小");
		}
		Date finishTime = DateUtils.stringToDate(activityReq.getFinishTime(), DateUtils.YYYY_MM_DD_HH_MM_SS);
		if (null == finishTime) {
			return R.failed("结束时间不合法");
		}
		if (finishTime.getTime() <= startTime.getTime()) {
			return R.failed("结束时间不能比开始时间小");
		}
		if (finishTime.getTime() < System.currentTimeMillis()) {
			return R.failed("结束时间不能比当前时间小");
		}
		if (2 == activityReq.getTimeType()) {
			if (null == activityReq.getValidDays() || activityReq.getValidDays() < 1) {
				return R.failed("动态时间时，有效天数不能少于1天");
			}
		} else {
			activityReq.setValidDays(0);
		}
		if (!CollectionUtils.isNotEmpty(activityReq.getGameList())) {
			return R.failed("游戏范围不能为空");
		}
		//activityReq.getAreaList() ==> [[父游戏ID,区服ID]]
		if (CollectionUtils.isNotEmpty(activityReq.getAreaList())) {
			for (String[] areaArr : activityReq.getAreaList()) {
				if (areaArr.length != 2) {
					return R.failed("区服范围数据不合法");
				}
				List<HbActivity> repeatList = activityAreaMapper
						.selectCountActivityRepeat(
								Long.valueOf(areaArr[0]),
								Long.valueOf(areaArr[1]),
								SourceTypeEnum.HB.getType(),
								ActivityStatusEnum.ACTIVITING.getStatus(),
								activityReq.getActivityType(),
								activityReq.getStartTime(),
								DateUtils.dateToString(DateUtils.addDays(finishTime, activityReq.getValidDays()), DateUtils.YYYY_MM_DD_HH_MM_SS),
								activityReq.getRoleType(),
								activityReq.getDynamicTypeId());
				if (CollectionUtils.isNotEmpty(repeatList)) {
					return R.failed("活动时间或父游戏或区服或起始条件与已有同类型活动重叠，操作失败");
				}
			}
		} else {
			return R.failed("区服范围不能为空");
		}
		HbActivity info = JSON.parseObject(JSON.toJSONString(activityReq), HbActivity.class);
		info.setActivityName(activityReq.getActivityName().trim());
		info.setActivityStatus(ActivityStatusEnum.READY.getStatus());
		info.setCreateTime(new Date());
		info.setCreateId(SecurityUtils.getUser().getId().longValue());
		info.setUpdateTime(new Date());
		info.setUpdateId(SecurityUtils.getUser().getId().longValue());
		activityMapper.insert(info);
		structureActivityRange(info.getId(), activityReq.getChannelList(), activityReq.getGameList(), activityReq.getAreaList());
		return R.ok();
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public R editActivity(ActivityReq activityReq) {
		if (null == activityReq.getId() || activityReq.getId() <= 0) {
			return R.failed("活动ID不能为空");
		}
		Date startTime = DateUtils.stringToDate(activityReq.getStartTime(), DateUtils.YYYY_MM_DD_HH_MM_SS);
		if (null == startTime) {
			return R.failed("开始时间不合法");
		}
		Date finishTime = DateUtils.stringToDate(activityReq.getFinishTime(), DateUtils.YYYY_MM_DD_HH_MM_SS);
		if (null == finishTime) {
			return R.failed("结束时间不合法");
		}
		HbActivity info = activityMapper.selectOne(new QueryWrapper<HbActivity>().eq("id", activityReq.getId()).lt("activity_status", ActivityStatusEnum.CLOSE.getStatus()));
		if (null == info) {
			return R.failed("当前状态无法进行编辑");
		}
		R<UserInfo> userInfo = remoteUserService.findUserByUserId(SecurityUtils.getUser().getId(), SecurityConstants.FROM_IN);
		String[] permissions = null;
		if (CommonConstants.SUCCESS.equals(userInfo.getCode())) {
			permissions = userInfo.getData().getPermissions();
		}
		if (null == permissions || permissions.length <= 0) {
			return R.failed("无法获取登录用户权限信息");
		}
		if (ActivityStatusEnum.ACTIVITING.getStatus().equals(info.getActivityStatus())) {
			if (!Arrays.asList(permissions).contains("hongbao_hbactivity_onlineedit")) {
				return R.failed("您暂无修改上线中活动的权限，请找管理员授权");
			}
			//判断开始时间
			if (startTime.compareTo(info.getStartTime()) != 0) {
				return R.failed("上线中的活动，开始时间不能修改");
			}
			if (finishTime.compareTo(info.getFinishTime()) < 0) {
				return R.failed("上线中的活动，结束时间不能比原结束时间小");
			}
			if (!info.getTimeType().equals(activityReq.getTimeType())) {
				return R.failed("上线中的活动，时间类型无法修改");
			}
			if (2 == info.getTimeType()) {
				if (activityReq.getValidDays() < info.getValidDays()) {
					return R.failed("上线中的活动，有效天数不能小于原有效天数");
				}
			}
			if (!info.getRoleType().equals(activityReq.getRoleType())) {
				return R.failed("上线中的活动，起始条件无法修改");
			}
			//上线中的，父游戏无法变更
			if (CollectionUtils.isNotEmpty(activityReq.getGameList())) {
				Set<Long> pgSet = new HashSet<Long>();
				for (int i = 0; i < activityReq.getGameList().size(); i++) {
					pgSet.add(Long.parseLong(activityReq.getGameList().get(i)[0]));
				}
				List<HbActivityGame> gameList = activityGameMapper.selectList(new QueryWrapper<HbActivityGame>().eq("activity_id", info.getId()).orderByAsc("game_id"));
				Set<Long> gameOldArr = new HashSet<Long>();
				if (CollectionUtils.isNotEmpty(gameList)) {
					for (HbActivityGame activityGame : gameList) {
						gameOldArr.add(activityGame.getGameId());
					}
				}
				if (!Arrays.equals(pgSet.toArray(), gameOldArr.toArray())) {
					return R.failed("已上线活动不支持变更父游戏");
				}
			}
		} else {
			if (startTime.getTime() < DateUtils.getStartTimeStamp()) {
				return R.failed("开始时间不能比当前日期0点小");
			}
			if (!Arrays.asList(permissions).contains("hongbao_hbactivity_edit")) {
				return R.failed("您暂无修改待上线活动的权限，请找管理员授权");
			}
		}
		if (finishTime.getTime() <= startTime.getTime()) {
			return R.failed("结束时间不能比开始时间小");
		}
		if (finishTime.getTime() < System.currentTimeMillis()) {
			return R.failed("结束时间不能比当前时间小");
		}
		if (2 == activityReq.getTimeType()) {
			if (null == activityReq.getValidDays() || activityReq.getValidDays() < 1) {
				return R.failed("动态时间时，有效天数不能少于1天");
			}
		} else {
			activityReq.setValidDays(0);
		}
		if (!CollectionUtils.isNotEmpty(activityReq.getGameList())) {
			return R.failed("游戏范围不能为空");
		}
		if (CollectionUtils.isNotEmpty(activityReq.getAreaList())) {
			for (String[] areaArr : activityReq.getAreaList()) {
				if (areaArr.length != 2) {
					return R.failed("区服范围数据不合法");
				}
				List<HbActivity> repeatList = activityAreaMapper
						.selectCountActivityRepeat(
								Long.valueOf(areaArr[0]),
								Long.valueOf(areaArr[1]),
								SourceTypeEnum.HB.getType(),
								ActivityStatusEnum.ACTIVITING.getStatus(),
								activityReq.getActivityType(),
								activityReq.getStartTime(), DateUtils.dateToString(DateUtils.addDays(finishTime, activityReq.getValidDays()), DateUtils.YYYY_MM_DD_HH_MM_SS),
								activityReq.getRoleType(),
								activityReq.getDynamicTypeId());
				if (CollectionUtils.isNotEmpty(repeatList)) {
					for (HbActivity activity : repeatList) {
						if (!activityReq.getId().equals(activity.getId())) {
							return R.failed("活动时间或父游戏或区服或起始条件与已有同类型活动重叠，操作失败");
						}
					}
				}
			}
		} else {
			return R.failed("区服范围不能为空");
		}
		info = JSON.parseObject(JSON.toJSONString(activityReq), HbActivity.class);
		info.setActivityName(activityReq.getActivityName().trim());
		info.setUpdateTime(new Date());
		info.setUpdateId(SecurityUtils.getUser().getId().longValue());
		activityMapper.updateById(info);
		structureActivityRange(info.getId(), activityReq.getChannelList(), activityReq.getGameList(), activityReq.getAreaList());
		//校验多个父游戏清空提现档次和红包礼包码
		if (ActivityStatusEnum.READY.getStatus().equals(info.getActivityStatus())) {
			List<Long> pGameList = activityGameMapper.selectGroupPgIdByActivityId(info.getId());
			if (CollectionUtils.isNotEmpty(pGameList) && pGameList.size() > 1) {
				cashConfigMapper.delete(new QueryWrapper<HbCashConfig>().eq("activity_id", info.getId()).eq("cash_type", 1));
				HbRedpackConfig param = new HbRedpackConfig();
				param.setDeleted(1);
				redpackConfigMapper.update(param, new QueryWrapper<HbRedpackConfig>().eq("activity_id", info.getId()).eq("type", 2));
			}
		}
		return R.ok();
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public R copyActivity(CopyActivityReq activityReq) {
		//判断时间段内是否存在同类型活动
		Date startTime = DateUtils.stringToDate(activityReq.getStartTime(), DateUtils.YYYY_MM_DD_HH_MM_SS);
		if (null == startTime) {
			return R.failed("开始时间不合法");
		}
		if (startTime.getTime() < DateUtils.getStartTimeStamp()) {
			return R.failed("开始时间不能比当前日期0点小");
		}
		Date finishTime = DateUtils.stringToDate(activityReq.getFinishTime(), DateUtils.YYYY_MM_DD_HH_MM_SS);
		if (null == finishTime) {
			return R.failed("结束时间不合法");
		}
		if (finishTime.getTime() <= startTime.getTime()) {
			return R.failed("结束时间不能比开始时间小");
		}
		if (finishTime.getTime() < System.currentTimeMillis()) {
			return R.failed("结束时间不能比当前时间小");
		}
		if (2 == activityReq.getTimeType()) {
			if (null == activityReq.getValidDays() || activityReq.getValidDays() < 1) {
				return R.failed("动态时间时，有效天数不能少于1天");
			}
		} else {
			activityReq.setValidDays(0);
		}
		if (!CollectionUtils.isNotEmpty(activityReq.getGameList())) {
			return R.failed("游戏范围不能为空");
		}
		//原活动的活动父游戏为单一的时候，复制后的不能改为多个
		List<Long> pGidsList = activityGameMapper.selectGroupPgIdByActivityId(activityReq.getCopyActivityId());
		if (null != pGidsList && 1 == pGidsList.size()) {
			Set<String> pGidsSet = new HashSet<String>();
			for (String[] gameArr : activityReq.getGameList()) {
				pGidsSet.add(gameArr[0]);
			}
			if (pGidsSet.size() > 1) {
				return R.failed("为防止礼包码红包以及游戏货币提现异常，当前复制的活动仅支持单个主游戏");
			}
		}
		if (CollectionUtils.isNotEmpty(activityReq.getAreaList())) {
			for (String[] areaArr : activityReq.getAreaList()) {
				if (areaArr.length != 2) {
					return R.failed("区服范围数据不合法");
				}
				List<HbActivity> repeatList = activityAreaMapper
						.selectCountActivityRepeat(
								Long.valueOf(areaArr[0]),
								Long.valueOf(areaArr[1]),
								SourceTypeEnum.HB.getType(),
								ActivityStatusEnum.ACTIVITING.getStatus(),
								activityReq.getActivityType(),
								activityReq.getStartTime(), DateUtils.dateToString(DateUtils.addDays(finishTime, activityReq.getValidDays()), DateUtils.YYYY_MM_DD_HH_MM_SS),
								activityReq.getRoleType(),
								activityReq.getDynamicTypeId());
				if (CollectionUtils.isNotEmpty(repeatList)) {
					return R.failed("活动时间或父游戏或区服或起始条件与已有同类型活动重叠，操作失败");
				}
			}
		} else {
			return R.failed("区服范围不能为空");
		}
		HbActivity info = JSON.parseObject(JSON.toJSONString(activityReq), HbActivity.class);
		info.setActivityName(activityReq.getActivityName().trim());
		info.setActivityStatus(ActivityStatusEnum.READY.getStatus());
		info.setCreateTime(new Date());
		info.setCreateId(SecurityUtils.getUser().getId().longValue());
		info.setUpdateTime(new Date());
		info.setUpdateId(SecurityUtils.getUser().getId().longValue());
		activityMapper.insert(info);
		structureActivityRange(info.getId(), activityReq.getChannelList(), activityReq.getGameList(), activityReq.getAreaList());
		if (CollectionUtils.isNotEmpty(activityReq.getCopyConfigList())) {
			boolean flag = false;
			List<Long> pGameList = activityGameMapper.selectGroupPgIdByActivityId(info.getId());
			if (CollectionUtils.isNotEmpty(pGameList) && pGameList.size() > 1) {
				flag = true;
			}
			if (activityReq.getCopyConfigList().contains(CopyActivityTypeEnum.HB.getType())) {
				copyActivityHb(activityReq.getCopyActivityId(), info.getId(), flag);
				// 更新活动奖池
				this.sumActivity(info.getId());
			}
			if (activityReq.getCopyConfigList().contains(CopyActivityTypeEnum.TXDC.getType())) {
				copyActivityTxdc(activityReq.getCopyActivityId(), info.getId(), flag);
			}
			if (activityReq.getCopyConfigList().contains(CopyActivityTypeEnum.GG.getType())) {
				copyActivityGg(activityReq.getCopyActivityId(), info.getId(), info.getStartTime(), info.getFinishTime());
			}
			if (activityReq.getCopyConfigList().contains(CopyActivityTypeEnum.BD.getType())) {
				copyActivityBd(activityReq.getCopyActivityId(), info.getId());
			}
			if (activityReq.getCopyConfigList().contains(CopyActivityTypeEnum.TZPZ.getType())) {
				copyActivityTzpz(activityReq.getCopyActivityId(), info.getId(), info.getStartTime(), info.getFinishTime());
			}
		}

		return R.ok();
	}

	@Transactional(rollbackFor = Exception.class)
	void copyActivityTzpz(Long copyActivityId, Long activityId, Date startTime, Date finishTime) {
		List<PopupNotice> list = popupNoticeMapper.selectList(new QueryWrapper<PopupNotice>().eq("source_id", copyActivityId).eq("source_type", 1).eq("deleted", Constant.DEL_NO));
		if (CollectionUtils.isNotEmpty(list)) {
			List<HbActivityChannel> activityChannelList;
			List<HbActivityGame> activityGameList;
			List<HbActivityArea> activityAreaList;
			for (PopupNotice popupNotice : list) {
				popupNotice.setId(null);
				popupNotice.setSourceId(activityId);
				popupNotice.setPopupStartTime(startTime);
				popupNotice.setPopupEndTime(finishTime);
				popupNotice.setPopupStatus(ActivityStatusEnum.READY.getStatus());
				popupNotice.setPopupTime(new Date());
				popupNotice.setCreateTime(new Date());
				popupNotice.setCreateId(SecurityUtils.getUser().getId().longValue());
				popupNotice.setUpdateTime(new Date());
				popupNotice.setUpdateId(SecurityUtils.getUser().getId().longValue());
				popupNotice.setOpenType(1);
				popupNotice.setShowType(1);
				popupNotice.setPushNode(4);
				popupNotice.setPopupOrient(1);
				popupNotice.setPopupSort(0);
				popupNotice.setSourceMold(0);
				popupNoticeMapper.insert(popupNotice);
				activityChannelList = activityChannelMapper.selectList(new QueryWrapper<HbActivityChannel>().eq("activity_id", activityId).eq("deleted", Constant.DEL_NO));
				if (CollectionUtils.isNotEmpty(activityChannelList)) {
					List<PopupNoticeChannel> popupNoticeChannelList = new ArrayList<PopupNoticeChannel>();
					PopupNoticeChannel popupNoticeChannel;
					for (HbActivityChannel activityChannel : activityChannelList) {
						popupNoticeChannel = new PopupNoticeChannel();
						popupNoticeChannel.setNoticeId(popupNotice.getId());
						popupNoticeChannel.setParentchl(activityChannel.getChannelCode());
						popupNoticeChannel.setChl(activityChannel.getChildChannelCode());
						popupNoticeChannel.setAppchl(activityChannel.getSubChannelCode());
						popupNoticeChannel.setChannelRange(activityChannel.getChannelRange());
						popupNoticeChannel.setDeleted(0);
						popupNoticeChannel.setCreateTime(new Date());
						popupNoticeChannel.setCreateId(SecurityUtils.getUser().getId().longValue());
						popupNoticeChannel.setUpdateTime(new Date());
						popupNoticeChannel.setUpdateId(SecurityUtils.getUser().getId().longValue());
						popupNoticeChannelList.add(popupNoticeChannel);
					}
					popupNoticeChannelMapper.insertBatchPopupNoticeChannel(popupNoticeChannelList);
				}
				activityGameList = activityGameMapper.selectList(new QueryWrapper<HbActivityGame>().eq("activity_id", activityId).eq("deleted", Constant.DEL_NO));
				if (CollectionUtils.isNotEmpty(activityGameList)) {
					List<PopupNoticeGame> popupNoticeGameList = new ArrayList<PopupNoticeGame>();
					PopupNoticeGame popupNoticeGame;
					for (HbActivityGame activityGame : activityGameList) {
						popupNoticeGame = new PopupNoticeGame();
						popupNoticeGame.setPgameId(activityGame.getGameId());
						popupNoticeGame.setChildGameId(activityGame.getChildGameId());
						popupNoticeGame.setGameRange(activityGame.getGameRange());
						popupNoticeGame.setNoticeId(popupNotice.getId());
						popupNoticeGame.setDeleted(0);
						popupNoticeGame.setCreateTime(new Date());
						popupNoticeGame.setCreateId(SecurityUtils.getUser().getId().longValue());
						popupNoticeGame.setUpdateTime(new Date());
						popupNoticeGame.setUpdateId(SecurityUtils.getUser().getId().longValue());
						popupNoticeGameList.add(popupNoticeGame);
					}
					popupNoticeGameMapper.insertBatchPopupNoticeGame(popupNoticeGameList);
				}
				activityAreaList = activityAreaMapper.selectList(new QueryWrapper<HbActivityArea>().eq("activity_id", activityId).eq("source_type", SourceTypeEnum.HB.getType()).eq("deleted", Constant.DEL_NO));
				if (CollectionUtils.isNotEmpty(activityAreaList)) {
					List<PopupNoticeArea> popupNoticeAreaList = new ArrayList<PopupNoticeArea>();
					PopupNoticeArea popupNoticeArea;
					for (HbActivityArea activityArea : activityAreaList) {
						popupNoticeArea = new PopupNoticeArea();
						popupNoticeArea.setPgameId(activityArea.getGameId());
						popupNoticeArea.setAreaId(activityArea.getAreaId());
						popupNoticeArea.setAreaRange(activityArea.getAreaRange());
						popupNoticeArea.setNoticeId(popupNotice.getId());
						popupNoticeArea.setDeleted(0);
						popupNoticeArea.setCreateTime(new Date());
						popupNoticeArea.setCreateId(SecurityUtils.getUser().getId().longValue());
						popupNoticeArea.setUpdateTime(new Date());
						popupNoticeArea.setUpdateId(SecurityUtils.getUser().getId().longValue());
						popupNoticeAreaList.add(popupNoticeArea);
					}
					popupNoticeAreaMapper.insertBatchPopupNoticeArea(popupNoticeAreaList);
				}
			}
		}
	}

	@Transactional(rollbackFor = Exception.class)
	void copyActivityBd(Long copyActivityId, Long activityId) {
		List<HbInvitationTop> list = invitationTopMapper.selectList(new QueryWrapper<HbInvitationTop>().eq("activity_id", copyActivityId).eq("deleted", Constant.DEL_NO));
		if (CollectionUtils.isNotEmpty(list)) {
			for (HbInvitationTop invitationTop : list) {
				invitationTop.setId(null);
				invitationTop.setActivityId(activityId);
				invitationTop.setCreateTime(new Date());
				invitationTop.setCreateId(SecurityUtils.getUser().getId().longValue());
				invitationTop.setUpdateTime(new Date());
				invitationTop.setUpdateId(SecurityUtils.getUser().getId().longValue());
			}
			invitationTopMapper.insertBatch(list);
		}
	}

	@Transactional(rollbackFor = Exception.class)
	void copyActivityGg(Long copyActivityId, Long activityId, Date startTime, Date finishTime) {
		List<HbActivityNotice> list = activityNoticeMapper.selectList(new QueryWrapper<HbActivityNotice>().eq("activity_id", copyActivityId).eq("deleted", Constant.DEL_NO));
		if (CollectionUtils.isNotEmpty(list)) {
			for (HbActivityNotice activityNotice : list) {
				activityNotice.setId(null);
				activityNotice.setActivityId(activityId);
				activityNotice.setStartTime(startTime);
				activityNotice.setFinishTime(finishTime);
				activityNotice.setNoticeStatus(ActivityStatusEnum.READY.getStatus());
				activityNotice.setCreateTime(new Date());
				activityNotice.setCreateId(SecurityUtils.getUser().getId().longValue());
				activityNotice.setUpdateTime(new Date());
				activityNotice.setUpdateId(SecurityUtils.getUser().getId().longValue());
			}
			activityNoticeMapper.insertBatch(list);
		}
	}

	@Transactional(rollbackFor = Exception.class)
	void copyActivityTxdc(Long copyActivityId, Long activityId, boolean flag) {
		List<HbCashConfig> list = cashConfigMapper.selectList(new QueryWrapper<HbCashConfig>().eq("activity_id", copyActivityId).eq("deleted", Constant.DEL_NO));
		if (CollectionUtils.isNotEmpty(list)) {
			List<HbCashConfig> insertList = null;
			for (HbCashConfig cashConfig : list) {
				cashConfig.setId(null);
				cashConfig.setActivityId(activityId);
				cashConfig.setGiftCode(null);
				cashConfig.setGiftAmount(0);
				cashConfig.setCreateTime(new Date());
				cashConfig.setCreateId(SecurityUtils.getUser().getId().longValue());
				cashConfig.setUpdateTime(new Date());
				cashConfig.setUpdateId(SecurityUtils.getUser().getId().longValue());
			}
			if (flag) {//过滤礼包码
				insertList = list.stream().filter(item -> 1 != item.getCashType()).collect(Collectors.toList());
			} else {
				insertList = list;
			}
			if (CollectionUtils.isNotEmpty(insertList)) {
				cashConfigMapper.insertBatch(insertList);
			}
		}
		List<HbCashLimit> cashLimitList = cashLimitMapper.selectList(new QueryWrapper<HbCashLimit>().eq("activity_id", copyActivityId).eq("deleted", Constant.DEL_NO));
		if (CollectionUtils.isNotEmpty(cashLimitList)) {
			for (HbCashLimit cashLimit : cashLimitList) {
				cashLimit.setId(null);
				cashLimit.setActivityId(activityId);
				cashLimit.setCreateTime(new Date());
				cashLimit.setCreateId(SecurityUtils.getUser().getId().longValue());
				cashLimit.setUpdateTime(new Date());
				cashLimit.setUpdateId(SecurityUtils.getUser().getId().longValue());
			}
			cashLimitMapper.insertBatch(cashLimitList);
		}
	}

	@Transactional(rollbackFor = Exception.class)
	void copyActivityHb(Long copyActivityId, Long activityId, boolean flag) {
		List<HbRedpackConfig> list = redpackConfigMapper.selectList(new QueryWrapper<HbRedpackConfig>().eq("activity_id", copyActivityId).eq("deleted", Constant.DEL_NO));
		if (CollectionUtils.isNotEmpty(list)) {
			List<HbRedpackConfig> insertList = null;
			for (HbRedpackConfig redpackConfig : list) {
				redpackConfig.setId(null);
				redpackConfig.setActivityId(activityId);
				if (HbRedpackTypeEnum.GIFT.getType().equals(redpackConfig.getType().toString())) {
					redpackConfig.setGiftAmount(0);
				}
				redpackConfig.setGiftCode(null);
				redpackConfig.setGiftGetcounts(0);
				redpackConfig.setCreateTime(new Date());
				redpackConfig.setCreateId(SecurityUtils.getUser().getId().longValue());
				redpackConfig.setUpdateTime(new Date());
				redpackConfig.setUpdateId(SecurityUtils.getUser().getId().longValue());
			}
			if (flag) {//过滤礼包码红包
				insertList = list.stream().filter(item -> 2 != item.getType()).collect(Collectors.toList());
			} else {
				insertList = list;
			}
			if (CollectionUtils.isNotEmpty(insertList)) {
				redpackConfigMapper.insertBatch(insertList);
			}
		}
	}

	/**
	 * @description: 活动范围维护
	 * @author yuwenfeng
	 * @date 2022/1/11 16:20
	 */
	@Transactional(rollbackFor = Exception.class)
	void structureActivityRange(Long activityId, List<String[]> channelList, List<String[]> gameList, List<String[]> areaList) {
		if (CollectionUtils.isNotEmpty(channelList)) {
			activityChannelMapper.delete(new QueryWrapper<HbActivityChannel>().eq("activity_id", activityId));
			HbActivityChannel activityChannel;
			for (String[] channelArr : channelList) {
				if (channelArr.length > 0) {
					activityChannel = new HbActivityChannel();
					activityChannel.setActivityId(activityId);
					if (1 == channelArr.length) {
						activityChannel.setChannelCode(channelArr[0]);
						activityChannel.setChannelRange(1);
					}
					if (2 == channelArr.length) {
						activityChannel.setChannelCode(channelArr[0]);
						activityChannel.setChildChannelCode(channelArr[1]);
						activityChannel.setChannelRange(2);
					}
					if (3 == channelArr.length) {
						activityChannel.setChannelCode(channelArr[0]);
						activityChannel.setChildChannelCode(channelArr[1]);
						activityChannel.setSubChannelCode(channelArr[2]);
						activityChannel.setChannelRange(3);
					}
					activityChannel.setCreateTime(new Date());
					activityChannel.setCreateId(SecurityUtils.getUser().getId().longValue());
					activityChannel.setUpdateTime(new Date());
					activityChannel.setUpdateId(SecurityUtils.getUser().getId().longValue());
					activityChannelMapper.insert(activityChannel);
				}
			}
		}
		if (CollectionUtils.isNotEmpty(gameList)) {
			activityGameMapper.delete(new QueryWrapper<HbActivityGame>().eq("activity_id", activityId));
			HbActivityGame activityGame;
			for (String[] gameArr : gameList) {
				if (gameArr.length > 0) {
					activityGame = new HbActivityGame();
					activityGame.setActivityId(activityId);
					if (1 == gameArr.length) {
						activityGame.setGameId(Long.valueOf(gameArr[0]));
						activityGame.setGameRange(1);
					}
					if (2 == gameArr.length) {
						activityGame.setGameId(Long.valueOf(gameArr[0]));
						activityGame.setChildGameId(Long.valueOf(gameArr[1]));
						activityGame.setGameRange(2);
					}
					activityGame.setCreateTime(new Date());
					activityGame.setCreateId(SecurityUtils.getUser().getId().longValue());
					activityGame.setUpdateTime(new Date());
					activityGame.setUpdateId(SecurityUtils.getUser().getId().longValue());
					activityGameMapper.insert(activityGame);
				}
			}
		}
		if (CollectionUtils.isNotEmpty(areaList)) {
			activityAreaMapper.delete(new QueryWrapper<HbActivityArea>().eq("activity_id", activityId).eq("source_type", SourceTypeEnum.HB.getType()));
			HbActivityArea activityArea;
			for (String[] areaArr : areaList) {
				activityArea = new HbActivityArea();
				activityArea.setActivityId(activityId);
				if (1 == areaArr.length) {
					activityArea.setGameId(Long.valueOf(areaArr[0]));
					activityArea.setAreaRange(1);
				}
				if (2 == areaArr.length) {
					activityArea.setGameId(Long.valueOf(areaArr[0]));
					activityArea.setAreaId(Long.valueOf(areaArr[1]));
					activityArea.setAreaRange(2);
				}
				activityArea.setSourceType(SourceTypeEnum.HB.getType());
				activityArea.setCreateTime(new Date());
				activityArea.setCreateId(SecurityUtils.getUser().getId().longValue());
				activityArea.setUpdateTime(new Date());
				activityArea.setUpdateId(SecurityUtils.getUser().getId().longValue());
				activityAreaMapper.insert(activityArea);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public R onlineActivity(OnlineActivityReq activityReq) {
		HbActivity info;
		if (ActivityStatusEnum.ACTIVITING.getStatus().equals(activityReq.getActivityStatus())) {
			info = activityMapper.selectOne(new QueryWrapper<HbActivity>().eq("id", activityReq.getId()).eq("activity_status", ActivityStatusEnum.READY.getStatus()));
			if (null == info) {
				return R.failed("当前状态无法上线");
			}
			if (info.getTotalCost().doubleValue() <= 0) {
				return R.failed("奖池价值为0无法上线");
			}
			if (info.getTotalInvestMoney().subtract(info.getExpendBalance()).doubleValue() <= 0) {
				return R.failed("注资余额小于等于0，无法上线");
			}
		} else if (ActivityStatusEnum.CLOSE.getStatus().equals(activityReq.getActivityStatus())) {
			info = activityMapper.selectOne(new QueryWrapper<HbActivity>().eq("id", activityReq.getId()).eq("activity_status", ActivityStatusEnum.ACTIVITING.getStatus()));
			if (null == info) {
				return R.failed("当前状态无法下线");
			}
		} else {
			return R.failed("操作参数不合法");
		}
		info.setActivityStatus(activityReq.getActivityStatus());
		info.setUpdateTime(new Date());
		info.setUpdateId(SecurityUtils.getUser().getId().longValue());
		activityMapper.updateById(info);
		//校验多个父游戏清空提现档次和红包礼包码
		List<Long> pGameList = activityGameMapper.selectGroupPgIdByActivityId(info.getId());
		if (org.apache.commons.collections.CollectionUtils.isNotEmpty(pGameList) && pGameList.size() > 1) {
			cashConfigMapper.delete(new QueryWrapper<HbCashConfig>().eq("activity_id", info.getId()).eq("cash_type", 1));
			HbRedpackConfig param = new HbRedpackConfig();
			param.setDeleted(1);
			redpackConfigMapper.update(param, new QueryWrapper<HbRedpackConfig>().eq("activity_id", info.getId()).eq("type", 2));
		}
		//将通知配置的待上线通知配置改为上线中
		if (ActivityStatusEnum.ACTIVITING.getStatus().equals(activityReq.getActivityStatus())) {
			popupNoticeMapper.onlineByActivityId(info.getId(), ActivityStatusEnum.ACTIVITING.getStatus());
		}
		return R.ok();
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public R editCashLimit(SetCashLimitReq activityReq) {
		HbActivity info = activityMapper.selectOne(new QueryWrapper<HbActivity>().eq("id", activityReq.getActivityId()).le("activity_status", ActivityStatusEnum.ACTIVITING.getStatus()));
		if (null == info) {
			return R.failed("当前状态无法设置");
		}
		HbCashLimit cashLimit = cashLimitMapper.selectOne(new QueryWrapper<HbCashLimit>().eq("activity_id", activityReq.getActivityId()).eq("cash_type", activityReq.getCashType()).eq("rule_type", CashRuleTypeEnum.DAYLIMIT.getType()));
		if (null == cashLimit) {
			cashLimit = new HbCashLimit();
			cashLimit.setActivityId(activityReq.getActivityId());
			cashLimit.setCashType(activityReq.getCashType());
			cashLimit.setRuleType(CashRuleTypeEnum.DAYLIMIT.getType());
			cashLimit.setRuleLimit(BigDecimal.valueOf(activityReq.getDayCashLimit()));
			cashLimit.setCreateTime(new Date());
			cashLimit.setCreateId(SecurityUtils.getUser().getId().longValue());
			cashLimit.setUpdateTime(new Date());
			cashLimit.setUpdateId(SecurityUtils.getUser().getId().longValue());
			cashLimitMapper.insert(cashLimit);
		} else {
			cashLimit.setRuleLimit(BigDecimal.valueOf(activityReq.getDayCashLimit()));
			cashLimit.setUpdateTime(new Date());
			cashLimit.setUpdateId(SecurityUtils.getUser().getId().longValue());
			cashLimitMapper.updateById(cashLimit);
		}
		return R.ok();
	}

	@Override
	public R<HbCashLimit> selectCashLimitByAidAndType(SelectCashLimitReq req) {
		return R.ok(cashLimitMapper.selectOne(new QueryWrapper<HbCashLimit>().eq("activity_id", req.getActivityId()).eq("cash_type", req.getCashType()).eq("rule_type", CashRuleTypeEnum.DAYLIMIT.getType())));
	}

	@Override
	public List<NodeData> selectGameTree() {
		List<Long> idsList = adRoleGameService.getOwnerRolePgIds();
		if (Objects.isNull(idsList) || idsList.size() == 0) {
			return null;
		}
		LambdaQueryWrapper<ParentGameDO> wrapper = new LambdaQueryWrapper();
		wrapper.gt(ParentGameDO::getStatus, 0).in(ParentGameDO::getId, idsList);
		List<ParentGameDO> list = parentGameDOMapperExt.selectList(wrapper);
		List<NodeData> nodeList = list.stream().map(parentGame -> {
			NodeData nodeData = new NodeData();
			nodeData.setNodeId(parentGame.getId() + "");
			nodeData.setNodeName(parentGame.getGname());
			return nodeData;
		}).collect(Collectors.toList());
		List<WanGameDO> wangameList = gameService.listByIds(adRoleGameService.getOwnerRoleGameIds());
		List<NodeParentData> allGameList = gameDOMapperExt.selectAllGameList();
		if (CollectionUtils.isNotEmpty(nodeList)) {
			for (NodeData node : nodeList) {
				List<NodeData> childNodeResultList = new ArrayList<NodeData>();
				List<NodeData> childNodeList = allGameList.stream().filter(n -> null != n.getPId() && node.getNodeId().equals(n.getPId())).map(p -> {
					NodeData nodeData = new NodeData();
					nodeData.setNodeId(p.getNodeId());
					nodeData.setNodeName(p.getNodeName());
					return nodeData;
				}).collect(Collectors.toList());
				if (CollectionUtils.isNotEmpty(childNodeList)) {
					for (NodeData childNodeData : childNodeList) {
						for (WanGameDO wanGame : wangameList) {
							if (childNodeData.getNodeId().equals(wanGame.getId().toString())) {
								childNodeResultList.add(childNodeData);
							}
						}
					}
				}
				node.setChildNodeList(childNodeResultList);
			}
		}
		return nodeList;
	}

	@Override
	public List<NodeData> selectAreaTree() {
		List<NodeData> nodeList = parentGameDOMapperExt.selectMainGameList();
		if (CollectionUtils.isNotEmpty(nodeList)) {
			List<NodeData> resultList = new ArrayList<NodeData>();
			NodeData resultNode;
			List<ParentGameArea> allGameAreaList = parentGameAreaMapper.selectList(new QueryWrapper<ParentGameArea>().eq("deleted", Constant.DEL_NO));
			for (NodeData node : nodeList) {
				List<ParentGameArea> gameAreaList = allGameAreaList.stream().filter(n ->null !=n.getParentGameId() &&  StringUtils.equals(n.getParentGameId().toString(),node.getNodeId())).collect(Collectors.toList());
				if (CollectionUtils.isNotEmpty(gameAreaList)) {
					resultNode = node;
					resultNode.setChildNodeList(convertList(gameAreaList));
					resultList.add(resultNode);
				}
			}
			return resultList;
		}
		return null;
	}

	@Override
	public List<NodeData> selectChannelTree() {
		List<NodeParentData> allParentChannelList = promotionChannelDOMapperExt.selectAllChannel();
		List<NodeParentData> allSubChannelList = wanGameChannelInfoDOMapperExt.selectAllSubNodeList();
		List<NodeParentData> mainChannelDataList = allParentChannelList.stream().filter(n -> StringUtils.isBlank(n.getPId())).collect(Collectors.toList());
		List<NodeData> channelList = mainChannelDataList.stream().map(item -> {
			NodeData nodeData = new NodeData();
			nodeData.setNodeId(item.getNodeId());
			nodeData.setNodeName(item.getNodeName());
			return nodeData;
		}).collect(Collectors.toList());
		if (CollectionUtils.isNotEmpty(channelList)) {
			List<NodeData> childChannelList;
			List<NodeData> subChannelList;
			List<NodeParentData> childChannelDataList;
			List<NodeParentData> subChannelDataList;
			for (NodeData node : channelList) {
				childChannelDataList = allParentChannelList.stream().filter(n -> StringUtils.isNotBlank(n.getPId()) && n.getPId().equals(node.getNodeId())).collect(Collectors.toList());
				childChannelList = childChannelDataList.stream().map(item -> {
					NodeData nodeData = new NodeData();
					nodeData.setNodeId(item.getNodeId());
					nodeData.setNodeName(item.getNodeName());
					return nodeData;
				}).collect(Collectors.toList());
				if (CollectionUtils.isNotEmpty(childChannelList)) {
					for (NodeData subNode : childChannelList) {
						subChannelDataList = allSubChannelList.stream().filter(n -> StringUtils.isNotBlank(n.getPId()) && n.getPId().equals(subNode.getNodeId())).collect(Collectors.toList());
						subChannelList = subChannelDataList.stream().map(item -> {
							NodeData nodeData = new NodeData();
							nodeData.setNodeId(item.getNodeId());
							nodeData.setNodeName(item.getNodeName());
							return nodeData;
						}).collect(Collectors.toList());
						if (CollectionUtils.isNotEmpty(subChannelList)) {
							subNode.setChildNodeList(subChannelList);
						}
					}
					node.setChildNodeList(childChannelList);
				}
			}
		}
		return channelList;
	}

	@Override
	public List<Long> selectActivityByGame(String gameName) {
		String[] arr = gameName.split(",");
		if (arr.length == 1) {
			return activityGameMapper.selectActivityIdByGame(Long.valueOf(arr[0]), 0L);
		} else if (arr.length == 2) {
			return activityGameMapper.selectActivityIdByGame(Long.valueOf(arr[0]), Long.valueOf(arr[1]));
		}
		return null;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void sumActivity(Long activityId) {
		HbActivity info = activityMapper.selectById(activityId);
		if (null != info) {
			Double totalInvestMoney = investRecordMapper.sumInvestMoney(activityId);
			Double totalCost = redpackConfigMapper.sumTotalCost(activityId);
			//不计算礼包码
			Double expendBalance = receivingRecordMapper.sumExpendBalanceExcludeGift(activityId, 2);
			info.setTotalInvestMoney(BigDecimal.valueOf(totalInvestMoney));
			info.setTotalCost(BigDecimal.valueOf(totalCost));
			info.setExpendBalance(BigDecimal.valueOf(Objects.isNull(expendBalance) ? 0 : expendBalance));
			activityMapper.updateById(info);
		}
	}

	@Override
	public void activityFinishJob(String param) {
		List<HbActivity> list = activityMapper.selectList(new QueryWrapper<HbActivity>().eq("activity_status", ActivityStatusEnum.ACTIVITING.getStatus()).le("DATE_ADD( finish_time, INTERVAL valid_days DAY )", DateUtils.getcurrentTime()));
		if (CollectionUtils.isNotEmpty(list)) {
			for (HbActivity activity : list) {
				activity.setActivityStatus(ActivityStatusEnum.CLOSE.getStatus());
				activity.setUpdateTime(new Date());
				activityMapper.updateById(activity);
			}
		}
	}

	/**
	 * 抽奖活动下线
	 * @param param
	 */
	@Override
	public void raffleActivityFinishJob(String param) {
		raffleActivityService.update(new RaffleActivity().setActivityStatus(3),
				Wrappers.<RaffleActivity>lambdaQuery()
						.eq(RaffleActivity::getActivityStatus, 2)
				.lt(RaffleActivity::getFinishTime, DateUtils.dateToString(new Date(), DateUtils.YYYY_MM_DD_HH_MM_SS)));
	}

	/**
	 * 活动过期消息通知
	 *
	 * @param param
	 * @return
	 */
	@Override
	public void activityFinishSendMsgJob(String param) {
		// 查询正在活动中的活动
		List<HbActivity> activityList = activityMapper.selectList(new QueryWrapper<HbActivity>().eq("activity_status", ActivityStatusEnum.ACTIVITING.getStatus()).ge("DATE_ADD( finish_time, INTERVAL valid_days DAY )", DateUtils.getcurrentTime()));
		if (CollectionUtils.isNotEmpty(activityList)) {
			// 判断活动是否小于小时过期 (静态活动时间)
			int hour = 72;
			List<HbActivity> staticTimeList = activityList.stream().filter(activity -> activity.getTimeType() == 1 && activity.getFinishTime().getTime() < System.currentTimeMillis() + (1000 * 60 * 60 * hour)).collect(Collectors.toList());
			if (CollectionUtils.isNotEmpty(staticTimeList)) {
				staticTimeList.forEach(activity -> {
					// 查询参与活动角色列表
					List<HbActivityRoleInfo> activityRoleInfoList = activityRoleInfoMapper.selectList(Wrappers.<HbActivityRoleInfo>lambdaQuery()
							.eq(HbActivityRoleInfo::getSourceType, 1)
							.eq(HbActivityRoleInfo::getActivityId, activity.getId())
							.eq(HbActivityRoleInfo::getDeleted, 0));
					if (CollectionUtils.isNotEmpty(activityRoleInfoList)) {
						List<String> roleIds = activityRoleInfoList.stream().map(HbActivityRoleInfo::getRoleId).distinct().collect(Collectors.toList());
						// 红包领取发送消息
						redPackReceivesendRoleMsg(hour, "redpack", activity, roleIds);
						// 可以提现发送消息
						moneyWithdrawalGrade(hour, "withdrawal", activity, activityRoleInfoList);
					}
				});
			}

			// 判断活动是否小于小时过期 (动态活动时间)
			List<HbActivity> moveTimeList = activityList.stream().filter(activity -> activity.getTimeType() == 2).collect(Collectors.toList());
			if (CollectionUtils.isNotEmpty(moveTimeList)) {
				moveTimeList.forEach(activity -> {
					// 查询参与活动角色列表
					List<HbActivityRoleInfo> activityRoleInfoList = activityRoleInfoMapper.selectList(Wrappers.<HbActivityRoleInfo>lambdaQuery()
							.eq(HbActivityRoleInfo::getSourceType, 1)
							.eq(HbActivityRoleInfo::getActivityId, activity.getId())
							.eq(HbActivityRoleInfo::getDeleted, 0));
					if (CollectionUtils.isNotEmpty(activityRoleInfoList)) {
						List<String> roleIds = activityRoleInfoList.stream().map(HbActivityRoleInfo::getRoleId).distinct().collect(Collectors.toList());
						// 角色类型: 0活跃角色 1新角色 2老角色
						if (0 == activity.getRoleType()) {
							// 判断角色活动是否快过期
							List<HbActivityRoleInfo> campaignTimeList = activityRoleInfoList.stream().filter(role -> Objects.nonNull(role.getCampaignTime())
									&& DateUtils.addDays(role.getCampaignTime(), activity.getValidDays()).getTime() < System.currentTimeMillis() + (1000 * 60 * 60 * hour)
							).collect(Collectors.toList());
							if (CollectionUtils.isNotEmpty(campaignTimeList)) {
								List<String> gameRoleIds = campaignTimeList.stream().map(HbActivityRoleInfo::getRoleId).collect(Collectors.toList());
								// 红包领取发送消息
								redPackReceivesendRoleMsg(hour, "redpack", activity, gameRoleIds);
							}
						} else if (1 == activity.getRoleType()) {
							//获取角色创建时间
							List<GameRole> roleList = gameRoleMapper.selectList(Wrappers.<GameRole>lambdaQuery().in(GameRole::getRoleId, roleIds).eq(GameRole::getDeleted, 0));
							// 判断角色活动是否快过期
							List<GameRole> gameRoleList = roleList.stream().filter(role -> Objects.nonNull(role.getCreateRoleTime())
									&& DateUtils.addDays(role.getCreateRoleTime(), activity.getValidDays()).getTime() < System.currentTimeMillis() + (1000 * 60 * 60 * hour)
							).collect(Collectors.toList());
							if (CollectionUtils.isNotEmpty(gameRoleList)) {
								List<String> gameRoleIds = gameRoleList.stream().map(GameRole::getRoleId).collect(Collectors.toList());
								// 红包领取发送消息
								redPackReceivesendRoleMsg(hour, "redpack", activity, gameRoleIds);
							}
						}
						// 可以提现发送消息
						moneyWithdrawalGrade(hour, "withdrawal", activity, activityRoleInfoList);
					}
				});
			}
		}
	}

	/**
	 * 红包可以领取发送消息
	 *
	 * @param hour
	 * @param activity
	 * @param roleIds
	 */
	public void redPackReceivesendRoleMsg(int hour, String key, HbActivity activity, List<String> roleIds) {
		if (CollectionUtils.isNotEmpty(roleIds)) {
			// 过滤已经推送角色消息
			List<String> gameRoleIds = roleIds.stream().filter(role -> StringUtils.isBlank(stringRedisTemplate.opsForValue().get(Constant.HB_ACTIVITY_MSG + key + "_" + hour + "_" + activity.getId() + "_" + role))).collect(Collectors.toList());
			if (CollectionUtils.isNotEmpty(gameRoleIds)) {
				// 查询角色是否有可领取未领的红包
				List<HbRedpackRoleInfo> redpackRoleInfoList = redpackRoleInfoMapper.selectList(Wrappers.<HbRedpackRoleInfo>lambdaQuery().eq(HbRedpackRoleInfo::getActivityId, activity.getId()).in(HbRedpackRoleInfo::getRoleId, gameRoleIds));
				if (CollectionUtils.isNotEmpty(redpackRoleInfoList)) {
					List<HbRedpackRoleInfo> redpackRoleInfoLists = redpackRoleInfoList.stream().filter(redRoleInfo -> redRoleInfo.getReceivedCount() < redRoleInfo.getReceivableCount()).collect(Collectors.toList());
					if (CollectionUtils.isNotEmpty(redpackRoleInfoLists)) {
						redpackRoleInfoLists.forEach(redRoleInfo -> {
							String redisKey = Constant.HB_ACTIVITY_MSG + key + "_" + hour + "_" + activity.getId() + "_" + redRoleInfo.getRoleId();
							String redisValue = stringRedisTemplate.opsForValue().get(redisKey);
							if (StringUtils.isBlank(redisValue) || "0".equals(redisValue)) {
								HbActivityRoleInfo activityRoleInfo = activityRoleInfoMapper.selectOne(Wrappers.<HbActivityRoleInfo>lambdaQuery()
										.eq(HbActivityRoleInfo::getSourceType, 1)
										.eq(HbActivityRoleInfo::getActivityId, activity.getId())
										.eq(HbActivityRoleInfo::getPgameId, redRoleInfo.getPgameId())
										.eq(HbActivityRoleInfo::getGameId, redRoleInfo.getGameId())
										.eq(HbActivityRoleInfo::getUserId, redRoleInfo.getUserId())
										.eq(HbActivityRoleInfo::getAreaId, redRoleInfo.getAreaId())
										.eq(HbActivityRoleInfo::getRoleId, redRoleInfo.getRoleId()));
								if (Objects.nonNull(activityRoleInfo)) {
									// 调用发送消息
									// overdueType 过期类型：0-红包过期；1-可提现金额过期
									final LocalDateTime now = LocalDateTime.now();
									String recordValue = new JSONObject()
											.fluentPut("eventType", 6)
											.fluentPut("eventTime", DATE_TIME_FORMATTER.format(now))
											.fluentPut("parentChl", activityRoleInfo.getParentchl())
											.fluentPut("chl", activityRoleInfo.getChl())
											.fluentPut("appChl", activityRoleInfo.getAppchl())
											.fluentPut("pGameId", redRoleInfo.getPgameId())
											.fluentPut("gameId", redRoleInfo.getGameId())
											.fluentPut("areaId", redRoleInfo.getAreaId())
											.fluentPut("userId", redRoleInfo.getUserId())
											.fluentPut("roleId", redRoleInfo.getRoleId())
											.fluentPut("activityId", redRoleInfo.getActivityId())
											.fluentPut("overdueType", 0)
											.toJSONString();
									log.info("发送kafka信息,活动到期角色红包未领：{}", recordValue);
									XxlJobLogger.log("发送kafka信息,活动到期角色红包未领：{}", recordValue);
									//kafkaTemplate.send(hbTopic, redRoleInfo.getRoleId(), recordValue.getBytes(StandardCharsets.UTF_8));
									hbActivityRoleInfoService.send(redRoleInfo.getRoleId(), recordValue.getBytes(StandardCharsets.UTF_8));
									// 更新redis缓存
									Long time = ((DateUtils.addDays(activity.getFinishTime(), activity.getValidDays()).getTime() - System.currentTimeMillis()) + 86400000);
									stringRedisTemplate.opsForValue().set(redisKey, "1", time, TimeUnit.MILLISECONDS);
								}
							}
						});
					}
				}
			}
		}
	}

	/**
	 * 可以提现发送消息
	 *
	 * @param hour
	 * @param key
	 * @param activity
	 * @param activityRoleInfoList
	 */
	public void moneyWithdrawalGrade(int hour, String key, HbActivity activity, List<HbActivityRoleInfo> activityRoleInfoList) {
		if (CollectionUtils.isNotEmpty(activityRoleInfoList)) {
			// 过滤已经推送的角色消息
			List<HbActivityRoleInfo> activityRoleInfos = activityRoleInfoList.stream().filter(activityRole -> StringUtils.isBlank(stringRedisTemplate.opsForValue().get(Constant.HB_ACTIVITY_MSG + key + "_" + hour + "_" + activityRole.getActivityId() + "_" + activityRole.getRoleId()))).collect(Collectors.toList());
			if (CollectionUtils.isNotEmpty(activityRoleInfos)) {
				List<HbCashConfig> cashConfigList = cashConfigMapper.selectList(Wrappers.<HbCashConfig>lambdaQuery().eq(HbCashConfig::getActivityId, activity.getId()).eq(HbCashConfig::getDeleted, 0));
				activityRoleInfos.forEach(activityRoleInfo -> {
					BigDecimal subtract = activityRoleInfo.getTotalCashIncome().subtract(activityRoleInfo.getTotalWithdrawalAmount());
					List<HbCashConfig> cashConfigs = cashConfigList.stream().filter(cashConfig -> subtract.compareTo(cashConfig.getCashMoney()) > -1).collect(Collectors.toList());
					if (CollectionUtils.isNotEmpty(cashConfigs)) {
						String redisKey = Constant.HB_ACTIVITY_MSG + key + "_" + hour + "_" + activity.getId() + "_" + activityRoleInfo.getRoleId();
						String redisValue = stringRedisTemplate.opsForValue().get(redisKey);
						if (StringUtils.isBlank(redisValue) || "0".equals(redisValue)) {
							// 调用发送消息
							// overdueType 过期类型：0-红包过期；1-可提现金额过期
							final LocalDateTime now = LocalDateTime.now();
							String recordValue = new JSONObject()
									.fluentPut("eventType", 6)
									.fluentPut("eventTime", DATE_TIME_FORMATTER.format(now))
									.fluentPut("pGameId", activityRoleInfo.getPgameId())
									.fluentPut("gameId", activityRoleInfo.getGameId())
									.fluentPut("parentChl", activityRoleInfo.getParentchl())
									.fluentPut("chl", activityRoleInfo.getChl())
									.fluentPut("appChl", activityRoleInfo.getAppchl())
									.fluentPut("areaId", activityRoleInfo.getAreaId())
									.fluentPut("userId", activityRoleInfo.getUserId())
									.fluentPut("roleId", activityRoleInfo.getRoleId())
									.fluentPut("activityId", activityRoleInfo.getActivityId())
									.fluentPut("overdueType", 1)
									.toJSONString();
							log.info("发送kafka信息,活动到期可以提现：{}", recordValue);
							XxlJobLogger.log("发送kafka信息,活动到期角色红包未领：{}", recordValue);
							//kafkaTemplate.send(hbTopic, recordValue.getBytes(StandardCharsets.UTF_8));
							hbActivityRoleInfoService.send(activityRoleInfo.getRoleId(), recordValue.getBytes(StandardCharsets.UTF_8));
							// 更新redis缓存
							Long time = ((DateUtils.addDays(activity.getFinishTime(), activity.getValidDays()).getTime() - System.currentTimeMillis()) + 86400000);
							stringRedisTemplate.opsForValue().set(redisKey, "1", time, TimeUnit.MILLISECONDS);
						}
					}
				});
			}
		}
	}

	@Override
	public R<List<NodeData>> selectAreaTreeByPgameIds(String pGgmeIds) {
		List<NodeData> nodeList;
		if("0".equals(pGgmeIds)){//所有父游戏
			nodeList=parentGameDOMapperExt.selectMainGameList();
		}else{
			String[] pGids = pGgmeIds.split(",");
			if (pGids.length == 0) {
				return R.failed("父游戏ID不能为空");
			}
			Long[] pids = new Long[pGids.length];
			for (int i = 0; i < pGids.length; i++) {
				pids[i] = Long.valueOf(pGids[i]);
			}
			nodeList = parentGameDOMapperExt.selectMainGameListByPid(pids);
		}
		if (CollectionUtils.isNotEmpty(nodeList)) {
			List<NodeData> resultList = new ArrayList<NodeData>();
			NodeData resultNode;
			List<ParentGameArea> gameAreaList;
			for (NodeData node : nodeList) {
				gameAreaList = parentGameAreaMapper.selectList(new QueryWrapper<ParentGameArea>().eq("parent_game_id", node.getNodeId()).eq("deleted", Constant.DEL_NO));
				if (CollectionUtils.isNotEmpty(gameAreaList)) {
					resultNode = node;
					resultNode.setChildNodeList(convertList(gameAreaList));
					resultList.add(resultNode);
				}
			}
			return R.ok(resultList);
		}
		return R.ok();
	}

	/**
	 * 红包活动下拉列表查询
	 *
	 * @param activityReq
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class, transactionManager = "adsTransactionManager")
	@Override
	public List<HbActivity> selectActivityList(SelectActivityPageReq activityReq) {
		final Integer activityType = activityReq.getActivityType();
		final Long dynamicTypeId = activityReq.getDynamicTypeId();
		return this.list(Wrappers.<HbActivity>lambdaQuery().select(HbActivity::getId, HbActivity::getActivityName)
				.eq(Objects.nonNull(activityType), HbActivity::getActivityType, activityType)
				.eq(Objects.nonNull(dynamicTypeId), HbActivity::getDynamicTypeId, dynamicTypeId)
				.eq(HbActivity::getDeleted, 0)
		);
	}

	/**
	 * 设置活动动态类型
	 * @param req
	 * @return
	 */
	@Override
	public R saveOrUpdateDynamicType(DynamicTypeReq req) {
		try {
			HbActivityDynamicType dynamicType = new HbActivityDynamicType();
			R result = checkParam(req, dynamicType);
			if (0 != result.getCode()){
				return result;
			}
			BeanUtils.copyProperties(req, dynamicType);
			if(Objects.isNull(req.getId())){
				dynamicType.setCreateId(Long.valueOf(SecurityUtils.getUser().getId()));
				hbActivityDynamicTypeMapper.insert(dynamicType);
			}else{
				dynamicType.setUpdateId(Long.valueOf(SecurityUtils.getUser().getId()));
				hbActivityDynamicTypeMapper.updateById(dynamicType);
			}
			return R.ok();
		} catch (Throwable t) {
			log.error("设置活动动态类型", t);
		}
		return R.failed("设置活动动态类型失败");

	}

	@Override
	public R deleteDynamicType(DynamicTypeReq req) {
		try {
			//删除了活动中, 只要有活动都不能删.eq(HbActivity::getActivityStatus, ActivityStatusEnum.ACTIVITING.getStatus())
			List<HbActivity> list = activityMapper.selectList(new QueryWrapper<HbActivity>().lambda().eq(HbActivity::getActivityType, req.getActivityType()).eq(HbActivity::getDynamicTypeId, req.getId()));
			if(CollectionUtils.isNotEmpty(list)){
				return R.failed("该活动类型存在配置的活动，不能删除！");
			}
			hbActivityDynamicTypeMapper.deleteById(req.getId());
			return R.ok();
		} catch (Throwable t) {
			log.error("设置活动动态类型", t);
		}
		return R.failed("活动动态类型删除失败");
	}

	private R checkParam(DynamicTypeReq req, HbActivityDynamicType dynamicType) {
		//判断名称是否重复【和谢维确认，不用限定这么死，可以重复】
		//新增
		/*if(Objects.isNull(req.getId())) {
			List<HbActivityDynamicType> list = hbActivityDynamicTypeMapper.selectList(new QueryWrapper<HbActivityDynamicType>().lambda().eq(HbActivityDynamicType::getShowName, req.getShowName()));
			if (CollectionUtils.isNotEmpty(list)) {
				return R.failed("名称存在重复数据");
			}
		//修改
		}else{
			List<HbActivityDynamicType> list = hbActivityDynamicTypeMapper.selectList(new QueryWrapper<HbActivityDynamicType>().lambda().eq(HbActivityDynamicType::getShowName, req.getShowName()).ne(HbActivityDynamicType::getId, req.getId()));
			if (CollectionUtils.isNotEmpty(list)) {
				return R.failed("名称存在重复数据");
			}
		}*/

		return  R.ok();
	}

	private List<NodeData> convertList(List<ParentGameArea> gameAreaList) {
		if (CollectionUtils.isNotEmpty(gameAreaList)) {
			List<NodeData> nodeList = new ArrayList<NodeData>();
			NodeData node;
			for (ParentGameArea gameArea : gameAreaList) {
				node = new NodeData();
				node.setNodeId(gameArea.getAreaId().toString());
				node.setNodeName(gameArea.getAreaName());
				nodeList.add(node);
			}
			return nodeList;
		}
		return null;
	}

	/**
	 * 更新kvpic
	 * @Description:
	 * @Author: zjz
	 * @Date: 2022/6/20
	 */
	@Override
	public R editKvpicActivity(KvpicActivityReq kvpicActivityReq){
		//todo 更新kvpic
		activityMapper.editKvpicActivity(kvpicActivityReq);
		return R.ok();
	}
}
